// ALERT: 此代码中涉及到的链表，默认都带头结点。

#include <stdio.h>
#define MaxSize 50


typedef int ElemType;

// FUNCTION: 定义顺序表
typedef struct {
	ElemType data[MaxSize];
	int length;
} SqList;


// FUNCTION: 插入元素
// @param: pos代表插入的位置，insert_target代表需插入的元素值
bool ListInsert(SqList &L, int pos, ElemType target) {
	printf("Start inserting element...\n");

	// NOTE: 插入操作合法性检查
	// STEP: 检查插入位置是否合法
	if (pos < 1 || pos > L.length + 1) {
		return false;
	}

	// STEP: 检查顺序表是否已满
	if (L.length >= MaxSize) {
		return false;
	}


	// NOTE: 执行插入操作
	// STEP: 移动带插入位置之后的元素
	for (int i = L.length; i >= pos; --i) {
		L.data[i] = L.data[i - 1];
	}

	// STEP: 插入数据
	L.data[pos - 1] = target;

	// STEP: 维护数据表长度
	++L.length;


	// NOTE: 操作成功结束返回
	return true;
}


// FUNCTION: 按位置删除元素
// @param: pos代表插入的位置，insert_target代表需插入的元素值
bool ListDelete_byPos(SqList &L, int pos) {
	printf("Start deleting by position...\n");

	// NOTE: 删除操作合法性检查
	// STEP: 检查删除位置是否合法
	if (pos < 1 || pos > L.length + 1) {
		return false;
	}

	// STEP: 检查顺序表是否已空
	if (L.length == 0) {
		return false;
	}


	// NOTE: 执行删除操作（默认，写0即删除）
	// STEP: 将待删元素写0
	L.data[pos - 1] = 0;

	// STEP: 从待删元素的后继元素开始，后继元素依次覆盖前一个元素
	for (int i = pos; i <= L.length; ++i) {
		L.data[i - 1] = L.data[i];
	}

	// STEP: 维护数据表长度
	--L.length;


	// NOTE: 操作成功结束返回
	return true;
}


// FUNCTION: 按值删除元素
// @param: pos代表插入的位置，insert_target代表需插入的元素值
bool ListDelete_byValue(SqList &L, ElemType target) {
	printf("Start deleting by value...\n");

	// NOTE: 插入操作合法性检查
	// STEP: 检查顺序表是否已空
	if (L.length == 0) {
		return false;
	}


	// NOTE: 执行删除操作
	// STEP: 设置临时变量，存储以后目标元素在顺序表中的索引
	int index = -1;

	// STEP: 遍历列表找到target是否在列表中
	for (int i = 0; i < L.length; ++i) {
		if (target == L.data[i]) {
			index = i;

			break;
		}
	}

	// STEP: 判定是否可执行删除操作
	if (index == -1) {
		printf("目标元素不存在！\n");

		return false;
	}

	// STEP: 从待删元素的后继元素开始，后继元素依次覆盖前一个元素
	for (int i = index + 1; i <= L.length; ++i) {
		L.data[i - 1] = L.data[i];
	}

	// STEP: 维护数据表长度
	--L.length;


	// NOTE: 操作成功结束返回
	return true;
}


// FUNCTION: 查询元素是否在顺序表内
// @param: target代表待查元素
int ListSeek(SqList L, ElemType target) {
	printf("Start querying...\n");

	// NOTE: 插入操作合法性检查
	// STEP: 检查顺序表是否已空
	if (L.length == 0) {
		return false;
	}


	// NOTE: 执行查询操作
	// STEP: 设置临时变量，存储以后目标元素在顺序表中的索引
	int index = -1;

	// STEP: 遍历列表找到target是否在列表中
	for (int i = 0; i < L.length; ++i) {
		if (target == L.data[i]) {
			index = i;

			break;
		}
	}

	// STEP: 判定是否可执行查询操作
	if (index == -1) {
		printf("目标元素不存在！\n");

		return index;
	} else {
		return index;
	}
}


// FUNCTION: 输出顺序表中全部元素
void ListPrint(SqList L) {
	// NOTE: 特殊值处理
	if (L.length == 0) {
		printf("SqList is empty!\n");

		return;
	}


	// NOTE: 执行输出操作
	// STEP: 移动带插入位置之后的元素
	printf("%d elements included. They are: ", L.length);
	for (int i = 0; i < L.length; ++i) {
		printf("%d ", L.data[i]);
	}
	printf("\n\n");
}


int main() {
	setbuf(stdout, NULL);

	// NOTE: Variable declaration
	// STEP: 创建一个顺序表对象
	SqList L;

	// STEP: 存储函数返回值
	bool ret;

	// STEP: 存储要删除的目标元素值
	ElemType delete_target;

	// STEP: 存储要插入的目标元素值
	ElemType insert_target;

	// STEP: 存储要查找的目标元素值
	ElemType query_target;

	// STEP: 需要进行操作的元素索的位置（索引值加1）
	int pos;

	// NOTE: Inputs（顺序表初始化——手动输入数据）
	// STEP: 向顺序表赋值
	L.data[0] = 1;
	L.data[1] = 2;
	L.data[2] = 3;

	// STEP: 修改当前表长
	L.length = 3;


	// bundle: 插入元素
	// NOTE: Process
	// STEP: 变量准备
	pos = 2;
	insert_target = 60;

	// STEP: 往元素位置为pos的元素中插入数据。
	ret = ListInsert(L, pos, insert_target);

	// STEP: 检测是否执行成功
	if (ret) { // 判断条件的等价写法：ret == true
		printf("Mission Success~~\n");
	} else {
		printf("Mission Failed!\n");
	}


	// NOTE: Outputs
	ListPrint(L);


	// bundle: 按元素位置删除元素
	// NOTE: Process
	// STEP: 变量准备
	pos = 2;

	// STEP: 往元素位置为pos的元素中插入数据。
	ret = ListDelete_byPos(L, pos);

	// STEP: 检测是否执行成功
	if (ret) { // 判断条件的等价写法：ret == true
		printf("Mission Success~~\n");
	} else {
		printf("Mission Failed!\n");
	}


	// NOTE: Outputs
	ListPrint(L);


	// bundle: 按元素数值删除元素
	// NOTE: Process
	// STEP: 变量准备
	delete_target = 2;
	// delete_target = 60;

	// STEP: 往元素位置为pos的元素中插入数据。
	ret = ListDelete_byValue(L, delete_target);

	// STEP: 检测是否执行成功
	if (ret) { // 判断条件的等价写法：ret == true
		printf("Mission Success~~\n");
	} else {
		printf("Mission Failed!\n");
	}


	// NOTE: Outputs
	ListPrint(L);


	// bundle: 查询元素是否在顺序表内
	// NOTE: Process
	// STEP: 变量准备
	query_target = 3;

	// STEP: 往元素位置为pos的元素中插入数据。
	int ret_index = ListSeek(L, query_target);

	// STEP: 检测是否执行成功
	if (ret) { // 判断条件的等价写法：ret == true
		printf("Mission Success~~\n");
	} else {
		printf("Mission Failed!\n");
	}


	// NOTE: Outputs
	// STEP: 输出查询结论
	if (ret_index) {
		printf("%d is found in SqList. Its index is %d, value is %d\n", query_target, ret, L.data[ret]);
	} else {
		printf("%d is not in this SqList!\n", query_target);
	}

	// STEP: 输出列表中所有元素
	ListPrint(L);

	// NOTE: Ending
	return 0;
}